﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace WindowsGame4
{
    public class GameObject
    {
        public enum Shape { Circle, Ray, Box };
        public Vector2 pos;
        public Vector2 vel, acc, scale;
        public Vector4 color;
        public Shape shape;
        public bool bDead, bOntimer;
        public bool bBlocks, bMoves, bCollides, bHardAttach, bVisible, bExplodeOnDeath;
        public float depth, angle, moveSpeed, moveAcc, lifeTime, rotSpeed;
        public Texture2D texture;
        public SpriteEffects effects;
        public GameObject attachTarget;
        public GameObject()
        {
            shape = Shape.Circle;
            bExplodeOnDeath = true;
            pos = new Vector2();
            vel = new Vector2();
            acc = new Vector2();
            scale = new Vector2(1,1);
            color = new Vector4(1, 1, 1, 1);
            bDead = false;
            lifeTime = 1.0f;
            bOntimer = false;
            bCollides = true;
            bBlocks = true;
            bMoves = true;
            bHardAttach = true;
            bVisible = true;
            rotSpeed = 0;
            texture = GameManager.texture;
            effects = SpriteEffects.None;
            depth = .5f;
            attachTarget = null;
        }
        public static Vector2 GetGlobal(Vector2 v=new Vector2())
        {
            Vector2 gv = v + GameManager.player.pos - GameManager.GetCenter();
            return gv;
        }
        public Vector2 GetCenter()
        {
            Vector2 center = pos + new Vector2(texture.Width / 2, texture.Height / 2);
            return center;
        }
        public virtual void Update(float time)
        {
            if (attachTarget != null)
            {
                if(bHardAttach)
                    pos = attachTarget.pos;
                vel = attachTarget.vel;
                acc = attachTarget.acc;
            }
            else
            {
                vel += acc * time;
                pos += vel * time;
            }
            angle += rotSpeed * time;
            if (bOntimer)
            {
                lifeTime -= time;
                if (lifeTime <= 0.0f)
                    bDead = true;
            }
        }
        public virtual void Draw(SpriteBatch batch)
        {
            Vector2 dir = pos - GameManager.player.pos;
            float distance = dir.Length();
            if (distance > GetRadius() + 467)
                return;
            else GameManager.nDrawn++;
            float rads=angle*(float)Math.PI/180;
            float cos = (float)Math.Cos(rads), sin = (float)Math.Sin(rads);
            dir= new Vector2(-texture.Width/2*scale.X,-texture.Height/2*scale.Y);
            Vector2 corner = pos + new Vector2(dir.X * cos - dir.Y * sin, dir.X * sin + dir.Y * cos);
            //fix the camera on center
            Vector2 view = GameManager.player.pos - GameManager.GetCenter();
            batch.Draw(texture, corner - view, null, new Color(color), rads, new Vector2(), scale, effects, depth);
        }
        public virtual void React(GameObject obj, Vector2 cp)
        {
            if(obj.bBlocks&&bBlocks)
                if (bMoves)
                    if (obj.bMoves)
                        Reflect(cp);
                    else Bounce(obj, cp);
        }
        public virtual void OnDeath()
        {

        }
        public void Reflect(Vector2 cp)
        {
            Vector2 n = pos - cp;
            if (n.Length() <= 0)
                return;
            n.Normalize();
            float dv=Vector2.Dot(vel, n);
            if (dv < 0)
                vel += 2 * dv * n;
        }
        public void Bounce(GameObject obj, Vector2 cp)
        {
            Vector2 n = pos - cp;
            if (n.Length() <= 0)
                return;
            n.Normalize();
            float dv = Vector2.Dot(vel - obj.vel, n);
            if (dv < 0)
                vel -= dv * n;
        }
        public float GetRadius()
        {
            float radius = Math.Max(texture.Width * scale.X, texture.Height * scale.Y)*.5f;
            return radius;
        }
        public virtual float GetRayWidth()
        {
            return texture.Height * scale.Y * .5f;
        }
        public static float GetAngle(Vector2 dir)
        {
            if (dir.Length() == 0)
                return 0;
            float angle = (float)(Math.Atan(dir.Y / dir.X) / Math.PI) * 180;
            if (dir.X < 0)
                angle -=180;
            return angle;
        }
        public static Vector2 GetDir(float angle)
        {
            Vector2 dir = new Vector2((float)Math.Cos(angle * Math.PI / 180), (float)Math.Sin(angle * Math.PI / 180));
            angle -= ((float)Math.Floor(angle / 360))*360;
            return dir;
        }
    }
}
